package com.zhixing.service.processor;

import com.zhixing.common.ISwaggerConstants;
import com.zhixing.model.SwaggerDefinitionModelAttr;
import com.zhixing.utils.JsonUtils;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.*;

/**
 * swagger 响应 json 解析处理器
 * @author zhixing
 */
public class SwaggerResponseProcessor implements SwaggerProcessor{
    /** json 解析后的 入参对象 **/
    @Getter
    private String                                  resultStr;

    @Getter
    private Map<String, Object>                     responseObj;

    @Getter
    private Map<String, SwaggerDefinitionModelAttr> definitionMap;



    private SwaggerResponseProcessor(){
        this.resultStr = "";
    }

    public static Builder createBuild(){
        return  new Builder();
    }

    public static class Builder{
        private SwaggerResponseProcessor processor;
        public Builder(){
            this.processor = new SwaggerResponseProcessor();
        }

        public Builder responseObj(Map<String, Object> responseObj){
            this.processor.responseObj = responseObj;
            return this;
        }

        public Builder definitionMap(Map<String, SwaggerDefinitionModelAttr> definitinMap){
            this.processor.definitionMap = definitinMap;
            return this;
        }

        public SwaggerResponseProcessor build(){
            return this.processor;
        }

    }

    @Override
    public SwaggerResponseProcessor process() throws IOException {
        doProcess();
        return this;
    }

    /**
     * 处理请求参数列表
     *
     * @return
     */
    private void doProcess() throws IOException{
        if (responseObj != null && responseObj.get(ISwaggerConstants.IPATHS.SCHEMA) != null) {
            Map<String, Object> schema = (Map<String, Object>) responseObj.get(ISwaggerConstants.IPATHS.SCHEMA);
            String type = (String) schema.get(ISwaggerConstants.IPATHS.FILED_TYPE);
            String ref = null;
            // 数组
            if (ISwaggerConstants.IDATA_TYPE.ARRAY.equals(type)) {
                Map<String, Object> items = (Map<String, Object>) schema.get(ISwaggerConstants.IDEFINITIONS.ITEMS);
                if (items != null && items.get(ISwaggerConstants.IDEFINITIONS.ITEMS_REF) != null) {
                    ref = (String) items.get(ISwaggerConstants.IDEFINITIONS.ITEMS_REF);
                }
            }
            // 对象
            if (schema.get(ISwaggerConstants.IDEFINITIONS.ITEMS_REF) != null) {
                ref = (String) schema.get(ISwaggerConstants.IDEFINITIONS.ITEMS_REF);
            }
            if (StringUtils.isNotEmpty(ref)) {
                SwaggerDefinitionModelAttr modelAttr = definitionMap.get(ref);
                if (modelAttr != null && !CollectionUtils.isEmpty(modelAttr.getProperties())) {
                    Map<String, Object> responseMap = new HashMap<>(8);
                    for (SwaggerDefinitionModelAttr subModelAttr : modelAttr.getProperties()) {
                        responseMap.put(subModelAttr.getName(), getValue(subModelAttr.getType(), subModelAttr));
                    }
                    resultStr = JsonUtils.writeJsonStr(responseMap);
                }
            }
        }
    }

    protected Object getValue(String type, SwaggerDefinitionModelAttr modelAttr) {
        int pos;
        if ((pos = type.indexOf(":")) != -1) {
            type = type.substring(0, pos);
        }
        switch (type) {
            case ISwaggerConstants.IDATA_TYPE.STRING:
                return "string";
                // 时间类型转为时间戳
            case ISwaggerConstants.IDATA_TYPE.STRING_DATE:
                return 1234567890;
            case ISwaggerConstants.IDATA_TYPE.INTEGER:
            case ISwaggerConstants.IDATA_TYPE.INTEGER_64:
            case ISwaggerConstants.IDATA_TYPE.INTEGER_32:
                return 0;
            case ISwaggerConstants.IDATA_TYPE.NUMBER:
                return 0.0;
            case ISwaggerConstants.IDATA_TYPE.BOOLEAN:
                return true;
            case ISwaggerConstants.IDATA_TYPE.FILE:
                return "(binary)";
            case ISwaggerConstants.IDATA_TYPE.ARRAY:
                List list = new ArrayList();
                Map<String, Object> map = new LinkedHashMap<>();
                if (modelAttr != null && !CollectionUtils.isEmpty(modelAttr.getProperties())) {
                    for (SwaggerDefinitionModelAttr subModelAttr : modelAttr.getProperties()) {
                        map.put(subModelAttr.getName(), getValue(subModelAttr.getType(), subModelAttr));
                    }
                }
                list.add(map);
                return list;
            case ISwaggerConstants.IDATA_TYPE.OBJECT:
                map = new LinkedHashMap<>();

                if(null != modelAttr && modelAttr.getType().contains(ISwaggerConstants.IDATA_TYPE.LOCALDATETIME)){
                    return "2021-04-31 00:00:00";
                }
                if(null != modelAttr && modelAttr.getType().contains(ISwaggerConstants.IDATA_TYPE.LOCALDATE)){
                    return "2021-04-31";
                }
                if (modelAttr != null && !CollectionUtils.isEmpty(modelAttr.getProperties())) {
                    for (SwaggerDefinitionModelAttr subModelAttr : modelAttr.getProperties()) {
                        map.put(subModelAttr.getName(), getValue(subModelAttr.getType(), subModelAttr));
                    }
                }
                return map;
            default:
                return null;
        }
    }
}
